/**
 * 
 */

package com.wutianyi.maven.vm;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import com.wutianyi.maven.constants.ResourceLoadType;
import com.wutianyi.maven.plugins.AutoConfigCompileMojo;
import com.wutianyi.maven.properties.ConfigProperties;
import com.wutianyi.maven.xml.ParserXmlDom4j;

/**
 * @author wutianyi
 * 
 */
public class TemplateWrap {
	
	private static Logger logger = Logger.getLogger(TemplateWrap.class);
	
	private VelocityEngine		velocityEngine;
	private VelocityContext		context;
	private ParserXmlDom4j		config;
	private ConfigProperties	properties;
	private String				resourceLoadType;
	private String				resourceLoadPath;
	private String				mode;

	/**
	 * @param config
	 * @param properties
	 * @param resourceLoadType
	 * @param resourceLoadPath
	 * @param mode
	 */
	public TemplateWrap(ParserXmlDom4j config, ConfigProperties properties, String resourceLoadType, String resourceLoadPath, String mode) {
		this.config = config;
		this.properties = properties;
		this.resourceLoadPath = resourceLoadPath;
		this.resourceLoadType = resourceLoadType;
		this.mode = mode;
		init();
	}
	
	public void mergeTemplate(String outputParentPath) {
		Map<String, String> generatorFiles = config.getGeneratorFiles();

		if(null == generatorFiles) {
			return;
		}
		for(Entry<String, String> entry : generatorFiles.entrySet()) {
			Template template = velocityEngine.getTemplate(entry.getKey(), "utf8");
			if(null == template) {
				continue;
			}
			PrintWriter pw = null;

			try {
				File file = new File(outputParentPath, entry.getValue());
				if(!file.getParentFile().exists()) {
					boolean result = file.getParentFile().mkdirs();
					if(result) {
						logger.info("[Make The Directory: ]" + file.getAbsolutePath());
					}
				}
				pw = new PrintWriter(new FileOutputStream(file));
				template.merge(context, pw);
			}catch(FileNotFoundException e) {
				e.printStackTrace();
			} finally {
				if(pw != null) {
					
					pw.close();
				}
			}
		}
	}
	
	public void mergeTemplate() {
		Map<String, String> generatorFiles = config.getGeneratorFiles();

		if(null == generatorFiles) {
			return;
		}

		for(Entry<String, String> entry : generatorFiles.entrySet()) {
			Template template = velocityEngine.getTemplate(entry.getKey(), "utf8");
			if(null == template) {
				continue;
			}
			PrintWriter pw = null;

			try {
				pw = new PrintWriter(new FileOutputStream(new File(AutoConfigCompileMojo.class.getResource("/").getFile(), entry.getValue())));
				template.merge(context, pw);
			}catch(FileNotFoundException e) {
				e.printStackTrace();
			} finally {
				if(pw != null) {
					
					pw.close();
				}
			}
		}
	}

	private void init() {

		velocityEngine = new VelocityEngine();
		if(ResourceLoadType.FILE.getType().equals(resourceLoadType)) {
			if(StringUtils.isBlank(resourceLoadPath)) {
				// 如果选择了以文件的方式进行文件加载，但是又没有制定path，则默认到根目录
				resourceLoadPath = System.getProperty("user.home");
			}
			velocityEngine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, resourceLoadPath);
		}else {
			velocityEngine.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
		}
		initContext();
	}

	/**
	 * 
	 */
	private void initContext() {

		context = new VelocityContext();
		context.put("mode", mode);

		Map<String, String> propertiesDefines = config.getProperties();
		Map<String, String> decriptions = config.getDescriptions();

		if(null == propertiesDefines) {
			return;
		}

		for(Entry<String, String> entry : propertiesDefines.entrySet()) {
			String key = entry.getKey();
			String defaultValue = entry.getValue();
			String description = decriptions.get(key);
			String value = properties.getProperties(key, defaultValue, description);
			context.put(key, value);
		}
	}

}
